home *** CD-ROM | disk | FTP | other *** search
- Path: fido.asd.sgi.com!austern
- From: Philippe Verdy <100105.3120@compuserve.com>
- Newsgroups: comp.std.c++
- Subject: Re: Must exception classes have copy constructors?
- Date: 09 Apr 1996 09:58:00 PDT
- Organization: CompuServe Incorporated
- Approved: austern@isolde.mti.sgi.com
- Message-ID: <4kca45$347@dub-news-svc-5.compuserve.com>
- NNTP-Posting-Host: isolde.mti.sgi.com
- X-Original-Date: 9 Apr 1996 00:13:57 GMT
- X-Auth: PGPMoose V1.1 PGP comp.std.c++
- iQBVAwUBMWqXGky4NqrwXLNJAQHcRAIAkIZK0gRgssBg1FMdnq9TmvBO2ouCX2mq
- tuEJSUX5i7kcGok400FDb0Povo2/m/4+JamjHv6Jwu9f75C/sy9d7Q==
- =n9UE
- Originator: austern@isolde.mti.sgi.com
-
- David Byrden <Goyra@iol.ie> s'Θcrit :
- > Alan Griffiths <aGriffiths@ma.ccngroup.com> wrote:
- > >Looking through the DWP I can't see any reason to require a copy
- > >constructor, but there are references to copying temporaries.
- > What DWP did you read? The January 96 version requires that the
- > "throw" statement have access to the copy constructor and destructor of a
- > thrown object.
- I have submitted an article which has been rejected
- (I don't know why) about copy constructors needed. What I meant
- is such a restriction about the copy constructor is only to
- allow cleaner exception handling, concerning stack unrolling.
- In effect, if the compiler dis not have access to the copy
- constructor, the exception catcher which effectively matches
- the exception in the current context should be limited to
- use references only on the object.
-
- Because an error catcher can catch only a base class of the
- thrown object, and not the full object, when the exception
- matches, the thrown object will have to be copied to a catcher
- variable which may have less members than the original thrown
- object. This copy will occur while the throwing function con-
- text is still active, because the original thrown object was
- constructed within the thrower and may still reference some
- fields which will be destructed by the stack unrolling algo-
- rithm once the catcher receives the focus to do the appro-
- priate action the handler require.
-
- The reason why I am putting this submission is that I don't
- know why this scheme does not allow resumable exceptions:
- after all, when an assertion fails in a function which has
- to throw an exception, it first constructs an exception object
- within its context, then calls a library function to perform
- the exception matching. Once the matching is found, this
- library first call the exception handler to perform the
- copy constructor to a temporary object with type equal to
- the one taken by the catcher. Then only the library returns
- to the exception thrower, which will perform sannity in its
- context, and return to its caller in exception state (may be
- by returning an extra flag in a register, or by modifying
- its return address to an laternate return address given by
- its caller, so that the caller can continue stack unrolling
- on its active block and eventually jump to the catcher block
- if the calling block was a try { } block.
-
- So if the catcher has temporarily access to the thrower's
- context which is still valid, I think that exceptions can
- be resumed:
- instead of just performing the copy contructor of the
- catched exception, the library could first enter into a
- status function whose execution will say if the exception
- can be recovered or not. If it cannot, this context can be
- chained to other pending resumable catchers, until one of
- them return a status that says the exception can be resumed.
-
- If no resumable catcher is found in this chain, then the
- library will return a "don't-resume" status to the thrower
- which will effectively destroy its own exception object, then
- will start the stack unrolling for an effective exception.
-
- But if a catcher returns a "resume" status, this status can
- be immediately returned to the thrower, which will continue
- as if the exception had not occured.
-
- This has several impacts on the code specification, because
- the programmer should have to specify whever its throw()
- invocation could resume or not. So this requires an additional
- keyword like throw_resumable(), which does not have the "goto"
- or "break" or "continue" or "return" semantics, in the fact
- that the exception is not fatal (the jump is conditional).
- The compiler would generate a different library call for this
- addtional operator.
-
- By the same way, a resumable error catcher could fail to find
- a way which will satisfy the resume condition indicated by
- the exception object. But there could be other resumable
- catchers pending. This gives the opportunity of the resumable
- exception catchers chain (this only adds a unique static code
- pointer in each execution thread). The rest of the storage for
- this chain can be allocated at the catch point.
-
- Finally, resumable exception handlers must indicate that they
- can resume the exception. The semantics of the standard
- catch() construct is not sufficient for it as the catcher code
- to execute is not od the same kind: a standard catch()
- handler executes its code once the exception has occured, in a
- constext where the thrower does not exists any more.
- So this requires another keyword or construction like
- catch_resumable() instead of catch().
-
- For this new construction, the copy constructor does not have
- to be invoked, because the thrower context is still valid, so
- a catch_resumable() handler can receive directly a reference
- to the thrown object. The code in that catcher must be quite
- short if the exception kind is a lack of resource, because
- the thrower context is still active.
-
- In order to indicate its intention of resuming the exception,
- this code should use a specific construct (for example: retry;
- without parameters, which means "cancel the pending exception
- and resume to the resumable thrower"). This would make the
- resumable catcher return a "resume" state to the exception
- library which will be reported to the thrower. In that case
- all it would have to do is just delete its temporary thrown
- object and continue the execution.
-
- Such resumable exceptions should be very useful for time-out
- exceptions, or device-not-ready exceptions (which may be
- resumed after the user has been noticed of it by an alert
- with choices like "Retry" or "Cancel"), or for exceptions
- caused by lack of resources (a resumable exception catcher
- could check if it can free up some of the resources indicated
- by the exception object, for example it could free up some
- unused cache-buffers to allow more memory for the thrower).
-
- This model has no-impact on the existing code, and will add
- overhead only when new keywords are in actions. All other
- semantics of stancard throw()/catch() pairs are preserved.
- What do you think of this model ?
-
- Example of resumable exceptions for out-of-memory:
- --------------
- in the catcher
- --------------
- struct OutOfMemory; // fatal exception
- struct NeedMemory
- : public OutOfMemory // resumable exception
- {
- NeedMemory(size_t size) : OutOfMemory(size) {}
- }
- ...
- try {
- ...
- function() // this can send a resumable exception
- ...
- }
- catch_resumable(NeedMemory &exc) {
- // check if can free up some memory for exc.size()
- if (can_resume == true)
- retry; // resume in the thrower
- } // cannot resume, check other catch_resumable() handlers now
- catch(OutOfMemory &exc) {
- // Fatal exception, or resumable exception could not be
- // resumed by an explicit use of "retry;" in any pending
- // resumable_catchers.
- // Make some cleanup required by this error.
- } // continue at end of try/catch construct
-
- ----------------------------------
- Now in the exception thrower code:
- ----------------------------------
- void function()
- {
- size_t size;
- ...
- int retries;
- for (retries = 2; --retries >= 0) {
- // needs some memory resource (size_t size)
- ...
- if (...can allocate size...)
- break; // exits the for loop
- if (retries == 0)
- throw OutOfMemory(size); // fatal
- throw_resumable NeedMemory(size);
- // if could resume, continue here
- } // retry loop
- if (retries < 0)
- throw OutOfMemory(size); // fatal
- // OK, resource allocation succeeded
- ...
- }
- ---
- [ comp.std.c++ is moderated. To submit articles: Try just posting with your
- newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
- comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
- Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
- Comments? mailto:std-c++-request@ncar.ucar.edu
- ]
-